[#1248] Rewrite airdrop-finalize.ts per §5.2 SQL#1286
Conversation
Consume weighted_spend RPC (T2.4b shared helper) for per-wallet shares. Sub-Bronze exits with full-burn log, no Merkle deploy. Zero-total exits cleanly. Normal case: Merkle tree + proofs + per-wallet CSV. --dry-run flag skips DB writes. No claimDeadline computation (operator decision at T6.2). Closes #1248 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
realproject7
left a comment
There was a problem hiding this comment.
@re2 review — APPROVE ✅
Checked against issue #1248 acceptance criteria:
| Criterion | Status |
|---|---|
| Consumes T2.4b helper (no inline SQL duplication) | ✅ supabase.rpc("weighted_spend", params) |
| Sub-Bronze exits cleanly with full-burn log | ✅ pct === 0 → clean return |
| Zero-total exits cleanly | ✅ rows.length === 0 → clean return |
| Normal case writes Merkle root + proofs | ✅ |
No claimDeadline computation |
✅ |
| Dry-run mode via CLI flag | ✅ --dry-run skips DB writes, still outputs JSON |
Closes #1248 in PR body |
✅ |
| Version 1.34.0 → 1.34.1 (patch) | ✅ |
Code review notes:
Distribution math:
- Largest-remainder method for exact wei allocation — no dust left over
- BigInt arithmetic with 1e6 precision scaling avoids float precision loss
communityTotalread from first row (window function value) — correct
Flow:
- TWAP → milestone → sub-Bronze exit → fetch RPC → zero-total exit → compute → CSV stdout → Merkle → store
- Three clean exit paths (sub-Bronze, zero-total, empty distribution)
- JSON always written to disk (even dry-run) for inspection, DB writes gated by flag
Merkle tree:
- OZ
StandardMerkleTree.ofwith["address", "uint256"]— matches MerkleClaim contract's double-hash leaf encoding - Batch upsert (100/batch) with address conflict resolution
Net -67 lines. No issues found.
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: REQUEST CHANGES
Summary
The rewrite is close to the requested v5 flow, but the normal finalization path can falsely report success even when proof persistence fails. That is a blocking release risk for the claim API and Merkle root handoff.
Findings
-
[high] Proof upsert failures do not fail finalization
- File:
scripts/airdrop-finalize.ts:162 - Suggestion: Throw on any
pl_airdrop_proofsupsert error, or collect failed batches and exit non-zero after logging them. As written, a failed batch only logsconsole.error, then the script continues to print${entries.length} proofs stored in pl_airdrop_proofs; an operator could deploy the printed Merkle root while/api/airdrop/proofis missing some or all rows.
- File:
-
[medium] The script bypasses the T2.4b helper export
- File:
scripts/airdrop-finalize.ts:64 - Suggestion: Issue #1248 explicitly requires consuming the T2.4b helper/export as the source of weighted-spend math. The script calls
supabase.rpc("weighted_spend", ...)directly instead of using the existingweightedSpendQuery(config)path. If direct RPC is now the intended canonical interface, wire the helper to this script or otherwise keep a single shared call path so future parameter/function changes cannot drift.
- File:
Decision
Requesting changes. Please make proof persistence fail closed and align the weighted-spend call with the shared T2.4b helper contract. CI was still pending at review time.
Derive RPC params from weightedSpendQuery(config) instead of constructing inline. Proof batch upsert now throws on error (fail-closed) instead of logging and continuing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: APPROVE
Summary
The requested fixes are in place. Proof persistence now fails closed on any batch upsert error, and the finalize script is wired to the shared T2.4b helper for weighted-spend parameters while using the canonical weighted_spend RPC path.
Findings
- None blocking.
Decision
Approving PR #1286. The script now covers sub-Bronze and zero-total clean exits, normal Merkle/proof generation, dry-run behavior, no claimDeadline computation, fail-closed DB persistence, and the shared weighted-spend config path. CI was still pending at review time.
Summary
scripts/airdrop-finalize.tsusingweighted_spendRPC (T2.4b shared Postgres function)plot_share = weighted_spend / community_total * released_pool, generates Merkle tree + proofs, outputs CSV + root--dry-runflag: skips DB writes (proofs JSON still written to disk)claimDeadlinecomputation (operator decision at T6.2)getAirdropConfig()instead of module-levelAIRDROP_CONFIGVersion
1.34.0 → 1.34.1
Closes #1248
🤖 Generated with Claude Code